package com.echat.messagesender.sender.sms;

import com.echat.messagesender.sender.bean.EchatSendSmsInfo;
import com.echat.messagesender.sender.bean.SendResult;
import com.echat.messagesender.sender.constant.Constants;
import com.echat.messagesender.sender.model.SmsTemplate;
import com.echat.messagesender.sender.model.SmsTemplateMapping;
import com.echat.messagesender.sender.service.SendLogService;
import com.echat.messagesender.sender.service.TemplateService;
import com.echat.messagesender.sender.util.JsonUtil;
import com.echat.messagesender.sender.util.TemplateUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Created by chenmohan on 2018/08/16
 *
 * @description
 */
@Log4j2
public class SmsSenderManager {

    ExecutorService smsProcessor = Executors.newFixedThreadPool(10);

    @Setter
    @Getter
    private List<SmsSender> smsSenderList;

    @Getter
    @Setter
    private Map<Long, SmsSender> smsSenderMap;

    @Autowired
    private SendLogService sendLogService;

    @Autowired
    TemplateService templateService;

    public boolean sendSms(EchatSendSmsInfo info) {
        //保存发送日志
        Future<Long> smsIdFutrue = smsProcessor.submit(() -> sendLogService.addFullSmsSendLog(info));
        StringBuilder sb = new StringBuilder();
        List<SmsSender> senders = smsSenderList;
            //如果指定了平台账号,那么就使用该账号发送邮件
        if(info.getPlatformAccountId()!=null){
            SmsSender sender = getSmsSenderMap().get(info.getPlatformAccountId());
            senders = Arrays.asList(new SmsSender[]{sender});
        }
        for (SmsSender sender : senders) {
            String platformName = sender.getPlatformName();
            sb.append(sb.length() == 0 ? platformName : Constants.RIGHT_ARRAW + platformName);
            if (doSendSms0(info, sender)) {
                //发送成功则直接返回
                Long smsId = getFutrue(smsIdFutrue);
                if (smsId == null) {
                    log.warn("【短信】 {} 发送短信[id={}]失败", platformName, getFutrue(smsIdFutrue));
                    continue;
                }
                SendResult sendResult = SendResult.builder()
                        .id(smsId)
                        .sendPlatformId(sender.getPlatformAccountId())
                        .memo(sb.toString())
                        .sendResult(true).build();
                smsProcessor.submit(() -> sendLogService.setSmsSendResult(sendResult));
                log.info("【短信】smsId[" + smsId + "],由"+platformName+"发送成功!");
                return true;
            } else {
                log.warn("【短信】{}发送短信[id={}]失败", platformName, getFutrue(smsIdFutrue));
            }
        }
        log.warn("【短信】短信[id={}]发送失败", getFutrue(smsIdFutrue));
        return false;
    }

    private boolean doSendSms0(EchatSendSmsInfo info, SmsSender sender) {
        ifTemplateIdNotNullAndProcessTemplate(info, sender);
        return sender.sendSms(info);
    }

    /**
     * 如果EchatSendEmailInfo中存在模板id，那么处理模板短信文本
     * @param info
     * @param sender
     */
    private void ifTemplateIdNotNullAndProcessTemplate(EchatSendSmsInfo info, SmsSender sender) {
        if (info.getTemplateId() == null) {
            return;
        }
        Long templateId = Long.valueOf(info.getTemplateId());
        SmsTemplateMapping mapping = templateService.getSmsTemplateMappingId(templateId, sender.getPlatformId());
        if (mapping != null) {
            info.setTemplateId(mapping.getPlatformTemplateId());
            return;
        }
        SmsTemplate template = templateService.getSmsTemplateById(templateId);
        if (info.getSmsContent() == null || template == null) {
            return;
        }
        Map<String, String> paramMap = JsonUtil.toMap(info.getVars());
        String translateContent = TemplateUtil.translate(template.getContent(), paramMap);
        info.setSmsContent(translateContent);
    }

    private <T> T getFutrue(Future<T> future) {
        try {
            return future.get();
        } catch (InterruptedException e) {
            log.error(e.getCause() + " , " + e.getMessage());
        } catch (ExecutionException e) {
            log.error(e.getCause() + " , " + e.getMessage());
        }
        return null;
    }

}
